home *** CD-ROM | disk | FTP | other *** search
/ L' Effet Pommier 3 / L'Effet Pommier - Volume 03.iso / Programmation / Alpha ƒ / Tcl / SystemCode / fill.tcl < prev    next >
Text File  |  1996-01-10  |  8KB  |  312 lines

  1. ####################################################################
  2. # Much by Vince Darley.
  3. #                                    created: 3/7/95 {7:49:47 pm} 
  4. #                                last update: 6/10/95 {10:41:50 am} 
  5. #  Author: Vince Darley
  6. #  E-mail: <mailto:vince@das.harvard.edu>
  7. #    mail: Division of Applied Sciences, Harvard University
  8. #          Oxford Street, Cambridge MA 02138, USA
  9. #  <http://www.das.harvard.edu/users/students/Vincent_Darley/>
  10. #  
  11. ####################################################################
  12.  
  13.  
  14. proc fillParagraph {} {
  15.     if {[getPos] == [selEnd]} {
  16.         fillOneParagraph
  17.     } else {    
  18.         set start [getPos]
  19.         set end [selEnd]
  20.         set p $start
  21.         while { $p < $end } {
  22.             goto $p
  23.             set p [fillParagraph]
  24.         }
  25.         goto $start
  26.     }
  27. }
  28.  
  29. proc fillOneParagraph {} {
  30.     global leftFillColumn fillColumn
  31.     
  32.     getWinInfo a
  33.     set tabs $a(tabsize)
  34.  
  35.     set pos [getPos]
  36.     # find nearest text to grab hold of 
  37.     # to try and maintain cursor position
  38.     if { [lookAt $pos] != " " } {
  39.         set grab [getText $pos [expr $pos +20]]
  40.         set grabdiff 0
  41.     } else {
  42.         backwardWord
  43.         set p2 [getPos]
  44.         set grab [getText $p2 [expr $pos +20]]
  45.         set grabdiff [expr $pos - $p2]
  46.     }
  47.     
  48.     set start [paraStart $pos] 
  49.     set end [paraFinish $pos]
  50.     # get the leading whitespace of the current line
  51.     set res [search -s -n -f 1 -r 1 "^\[ \t\]*" [lineStart $pos]]
  52.     
  53.     # convert it to minimal form: tabs then spaces, stored in 'front'
  54.     set sp [string range "              " 1 $tabs ]
  55.     regsub -all $sp [eval getText $res] "\t" front
  56.     regsub -all "\[ \]+\t" $front "\t" front
  57.     # get the length of the indent
  58.     regsub -all "\t" $front $sp lfront
  59.     set left [string length $lfront]
  60.  
  61.     # fill the text
  62.     regsub -all "\[ \t\r\]+" [string trim [getText $start $end]] " " text
  63.     # turn single spaces at end of sentences into double
  64.     regsub -all {(([^A-Z@]|\\@)[.?!]([])]|'|'')?) } $text {\1  } text
  65.     
  66.     # temporarily adjust the fillColumns
  67.     set ol $leftFillColumn
  68.     set or $fillColumn
  69.     set leftFillColumn 0
  70.     set fillColumn [expr $fillColumn - $left]
  71.         
  72.     # break and indent the paragraph
  73.     regsub -all "\r" "\r[string trimright [breakIntoLines $text]]" "\r${front}" text
  74.     
  75.     # don't replace if nothing's changed
  76.     if { "$text\r" != "\r[getText $start $end]" } {
  77.         replaceText $start $end "[string range "$text" 1 end]\r"
  78.         set p [fillFind $text $grab]
  79.         if { $p == -1 } {
  80.             goto $pos
  81.         } else {
  82.             goto [expr $start + $p + $grabdiff -1]
  83.         }
  84.     }
  85.     
  86.     set leftFillColumn $ol
  87.     set fillColumn  $or
  88.     # in case we wish to fill a region
  89.     return $end
  90. }
  91.  
  92.  
  93. proc fillFind { text search } {
  94.     if { ![string length $search] } {
  95.         return -1
  96.     }
  97.     
  98.     set pos [string first $search $text]
  99.     if { $pos != -1 } {
  100.         return $pos
  101.     } else {
  102.         set search [string range $search 0 [expr [string length $search] -5]]
  103.         return [fillFind $text $search]
  104.     }
  105. }
  106.  
  107. set texParaCommands {begin|end|(protect\\)?label|(sub)*section|subfigure|paragraph|center(line|ing)|caption|chapter|item|bibitem|intertext}
  108.  
  109. proc paraStart {pos} {
  110.     global mode texParaCommands
  111.     if {$pos == [maxPos]} {incr pos -1}
  112.     set pos [lineStart $pos]
  113.     if { $mode == "TeX" || $mode == "Bib" } {
  114.         set startPara {(\\\\[ \t]*$|^[ \t]*(\$\$[ \t]*|(%+.*|(\\(}
  115.         append startPara $texParaCommands {)(\[.*\]|\{.*\}|Ñ)*[ \t]*)+))?$)}
  116.     } else {
  117.         set startPara {^([ \t]*|([\\%].*))$}
  118.     }
  119.     set res [search -s -n -f 0 -r 1 -l 0 "$startPara" $pos]
  120.     if {![string length $res] || $res == "0 0" } {return 0}
  121.     if { [lindex $res 0] == $pos } {
  122.         return $pos
  123.     } else {
  124.         return [nextLineStart [lindex $res 0]]
  125.     }
  126.     
  127. }
  128.  
  129. proc paraFinish {pos} {
  130.     global mode texParaCommands
  131.     set pos [lineStart $pos]
  132.     set end [maxPos]
  133.     if { $mode == "TeX" || $mode == "Bib" } {
  134.         set endPara {^[ \t]*(\$\$[ \t]*|(%+.*|(\\(}
  135.         append endPara $texParaCommands {)(\[.*\]|\{.*\}|Ñ)*[ \t]*)+))?$}
  136.     } else {
  137.         set endPara {^([ \t]*|([\\%].*))$}
  138.     }
  139.     
  140.     set res [search -s -n -f 1 -r 1 -l $end "$endPara" $pos]
  141.     if {![string length $res]} {return $end}
  142.     if { [lindex $res 0] == $pos } {
  143.         return [nextLineStart $pos]
  144.     }
  145.     # a line which ends in '\\' or '%' also signifies end of line in tex mode
  146.     if { $mode == "TeX" || $mode == "Bib" } {
  147.         set res2 [search -s -n -f 1 -r 1 -l $end {(\\\\|%)[ \t]*$} $pos]
  148.         if [string length $res2] {
  149.             if { [lindex $res2 0] < [lindex $res 0] } {
  150.                 return [nextLineStart [lindex $res2 0]]
  151.             }
  152.         }
  153.     }
  154.  
  155.     return [lindex $res 0]
  156.     
  157. }
  158.  
  159.  
  160. proc sentenceParagraph {} {
  161.     set pos [getPos]
  162.     set start [paraStart $pos] 
  163.     set finish [paraFinish $pos]
  164.  
  165.     set t [string trim [getText $start $finish]]
  166.     set period [regexp {\.$} $t]
  167.     regsub -all "\[ \t\r\]+" $t " " text
  168.     regsub -all {\. } $text "╞" text
  169.     set result ""
  170.     foreach line [split [string trimright $text {.}] "╞"] {
  171.         if {[string length $line]} {
  172.             append result [breakIntoLines $line] ".\r"
  173.         }
  174.     }
  175.     if {!$period && [regexp {\.\r} $result]} {
  176.         set result [string trimright $result ".\r"]
  177.         append result "\r"
  178.     }
  179.     if {$result != [getText $start $finish]} {
  180.         replaceText $start $finish $result
  181.     }
  182.     goto $pos
  183. }
  184.  
  185. proc getEndpts {} {
  186.     if {[getPos] == [selEnd]} {
  187.         set start [getPos]
  188.         set finish [getMark]
  189.         if {$start > $finish} {
  190.             set temp $start
  191.             set start $finish
  192.             set finish $temp
  193.         }
  194.     } else {
  195.         set start [getPos]
  196.         set finish [selEnd]
  197.     }
  198.     return [list $start $finish]
  199. }
  200.  
  201.  
  202. proc fillRegion {} {
  203.         global leftFillColumn
  204.         set ends [getEndpts]
  205.         set start [lineStart [lindex $ends 0]]
  206.         set finish [lindex $ends 1]
  207.         goto $start
  208.         set text [fillText $start $finish]
  209.         replaceText $start $finish [format "%$leftFillColumn\s" ""] $text "\r"
  210. }
  211.     
  212. proc wrapParagraph {} {
  213.     set pos [getPos]
  214.     set start [paraStart $pos] 
  215.     set finish [paraFinish $pos]
  216.     goto $start
  217.     wrapText $start $finish
  218.     goto $pos
  219. }
  220.  
  221. proc wrapRegion {} {
  222.     set ends [getEndpts]
  223.     set start [lineStart [lindex $ends 0]]
  224.     set finish [lindex $ends 1]
  225.     if {$start == $finish} {
  226.         set finish [maxPos]
  227.     }
  228.     wrapText $start $finish
  229. }
  230.     
  231.  
  232.  
  233. # Remove text from window, transform, and insert back into window.
  234. proc fillText {from to} {
  235.     set text [getText $from $to]
  236.     regexp {^ *} $text front
  237.     set text [string trim $text]
  238.     regsub -all "\[ \t\r\]+" $text " " text
  239.     regsub -all {(\.|\?|\!) } $text {\1  } text
  240.     regsub -all "\r" [string trimright [breakIntoLines $text]] "\r${front}" text
  241.     return $front$text
  242. }
  243.  
  244. proc paragraphToLine {} {
  245.     global fillColumn
  246.     global leftFillColumn
  247.     set fc $fillColumn
  248.     set lc $leftFillColumn
  249.     set fillColumn 10000
  250.     set leftFillColumn 0
  251.     fillRegion
  252.     set fillColumn $fc
  253.     set leftFillColumn $lc
  254. }
  255.  
  256. proc lineToParagraph {} {
  257.     global fillColumn
  258.     global leftFillColumn
  259.     set fc $fillColumn
  260.     set fillColumn 75
  261.     set lc $leftFillColumn
  262.     set leftFillColumn 0
  263.     fillRegion
  264.     set fillColumn $fc
  265.     set leftFillColumn $lc
  266. }
  267.  
  268.  
  269. #set sentEnd {[.!?](\r| +)}
  270. set sentEnd {(\r\r|[.!?](\r| +))}
  271. set sentBeg {[\r ][A-Z]}
  272.  
  273. proc nextSentence {} {
  274.     global sentBeg sentEnd
  275.     if {![catch {search -s -f 1 -r 1 $sentEnd [getPos]} mtch]} {
  276.         if {![catch {search -s -f 1 -r 1 -i 0 $sentBeg [expr [lindex $mtch 1]-1]} mtch]} {
  277.             goto [expr [lindex $mtch 0]+1]
  278.         }
  279.     }
  280. }
  281.  
  282.  
  283. proc prevSentence {} {
  284.     global sentBeg sentEnd
  285.     if {[catch {search -s -f 0 -r 1 $sentBeg [expr [getPos]-2]} mtch]} return
  286.     if {![catch {search -s -f 0 -r 1 $sentEnd [lindex $mtch 1]} mtch]} {
  287.         if {![catch {search -s -f 1 -r 1 -i 0 $sentBeg [expr [lindex $mtch 1]-1]} mtch]} {
  288.             goto [expr [lindex $mtch 0]+1]
  289.         }
  290.     }
  291. }
  292. # 5 730 845 955
  293.  
  294. #===============================================================================
  295. # Called by Alpha to do "soft wrapping"
  296. proc softProc {pos start next} {
  297.     global leftFillColumn
  298.     goto $start
  299.     set finish [paraFinish $start]
  300.     set text [fillText $start $finish]
  301.     if {"${text}\r" != [getText $start $finish]} {
  302.         replaceText $start $finish [format "%$leftFillColumn\s" ""] $text "\r"
  303.         return 1
  304.     } else {
  305.         return 0
  306.     }
  307. }
  308.  
  309.  
  310.